package com.log.com.log.service.impl;

import java.io.File;
import java.util.Calendar;
import java.util.Collections;

import com.log.com.log.bean.DeleLogBean;

/**
 * 利用了单例模式
 * 删除日志的service
 * @author dell
 *
 */
public class DeleLogService extends Thread {

	/**
	 * 添加一个bean
	 */
	private DeleLogBean  bean;
	
	private static DeleLogService  deleLogService=null;
	/**
	 * 构造器
	 */
	public DeleLogService(DeleLogBean bean) {
				this.bean=bean;
	}
	
	/**
	 * 单例模式  构造用的是懒加载  应该有线程安全问题  
	 * 后期需要测试是否需要更改
	 * @return
	 */
	public static DeleLogService getInstance(DeleLogBean bean){
		if(deleLogService==null){
			deleLogService=new  DeleLogService(bean);
			deleLogService.setName("DeleLogService");
		}
		return deleLogService;
	}
	
	
	@Override
	public synchronized void start() {
		if(getState()==Thread.State.NEW){
			setDaemon(false);   //用户线程  false  守护线程true
			super.start();
		}
	}
	
	
	@Override
	public void run() {
		
		while(true){
			
			long time=System.currentTimeMillis();
			Calendar nowTime=Calendar.getInstance();
			nowTime.setTimeInMillis(nowTime.getTimeInMillis()-bean.getMaxLogFileKeepTime());
			
			bean.setTotalSize(0L);
			
			for(File logPath:bean.getLogFile()){
				
				if(!logPath.exists()){
					continue;
				}
				
				if(!logPath.isDirectory()){
					continue;
				}
				//删除旧的文件
				deleOldFiles(nowTime,logPath);
				getTotalSize(logPath);
			}
			/**
			 * 1目录总和大于我们所规定的大小
			 * 2找到目录中文件的最早的一天目录（可以多个）
			 * 3删除目录中最的一小时的文件直到文件的的大小小于规定值
			 * 4如果删除目录里面的文件后 移除目录
			 * 4 每次删除100个文件 防止删除失败后无限尝试
			 */
			if(bean.getTotalSize()>bean.getTotalLogSize()){
				bean.getFile().clear();
				for(File file :bean.getLogFile()){
					getFilelist(file);
				}
				deleOlderFile();
			}
			
			long timeSpace=bean.getLogCheckTime()-(System.currentTimeMillis()-time);
			if(timeSpace>0){
				try {
					Thread.sleep(timeSpace);
				} catch (InterruptedException e) {
					System.out.println("睡死了。。。。。");
					e.printStackTrace();
				}
			}
			
		}
		
	
	}
	
	/**
	 * 删除早期文件超过规定时间的文件
	 *  文件进行排序
	 */
	private void deleOlderFile() {
		if(bean.getFile().isEmpty()){
			return ;
		}
		
		Collections.sort(bean.getFile(), new CompareSortService());
		
		while(bean.getTotalSize()/1024>bean.getTotalLogSize()){
			
			if(bean.getFile().isEmpty() || bean.getFile().size()==1){
				return ;
			}
			
			File file=bean.getFile().remove(0);
			long fileLength=file.length();
			if(file.delete()){
				bean.setTotalSize(bean.getTotalSize()-fileLength);
			}else{
				System.out.println("删除出错");
			}
			
			
		}
	}

	/**
	 * 得到文件临时保存起来
	 * @param file
	 */
	private void getFilelist(File file) {
		
		if(file==null || !file.exists()){
			return ;
		}
	
		if(file.isDirectory()){
			for(File f:file.listFiles()){
				getFilelist(f);
			}
		}else{
			if(file.exists()){
				bean.getFile().add(file);
			}
		}
		
		
			
		}

	/**
	 * 计算现在的文件大小  
	 * @param logPath
	 */
	private void getTotalSize(File logPath) {
		

		if(logPath.isDirectory()){
			if(logPath.listFiles()==null){
				return ;
			}
			for(File file:logPath.listFiles()){
				getTotalSize(file);
			}
			
		}else{
			bean.setTotalSize(bean.getTotalSize()+logPath.length());
		}
		
		
	}

	/**
	 * 删除文件  根据时间删除  目录可以隔开一个周期
	 * @param nowTime  现在的时间
	 * @param logPath  文件路径
	 */
	private void deleOldFiles(Calendar nowTime, File logPath) {
		
		if(logPath ==null || !logPath.exists()){
			return ;
		}
		
		Calendar calender=Calendar.getInstance();
		
		if(!logPath.isDirectory()){
			calender.setTimeInMillis(logPath.lastModified());
			File[] files=logPath.listFiles();
			
			if(files==null){
				return;
			}
			
			if(files.length>0){
				for(File f:files){
					deleOldFiles(calender, logPath);
				}
				
				//递归后删除空的目录
				if(files.length==0){
					if(calender.before(nowTime)){
						boolean delete=logPath.delete();
					}
				}
				
			}else{

				//递归后删除空的目录
				if(files.length==0){
					if(calender.before(nowTime)){
						boolean delete=logPath.delete();
					}
				}
				
			}
		}else{
			if(logPath.exists()){
				calender.setTimeInMillis(logPath.lastModified());
				if(calender.before(nowTime)){
					try {
						boolean delete=logPath.delete();
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
				
			
			}
		}
		
	}
	
}
